<?php

namespace app\validate;

use mon\util\Instance;
use mon\util\Validate;

/**
 * Auth 验证器
 *
 * Class Auth
 * @copyright 2021-03-24 mon-console
 * @version 1.0.0
 */
class Auth extends Validate
{
    use Instance;

    /**
     * 验证规则
     *
     * @var array
     */
    public $rule = [
        'idx'           => ['required', 'int', 'min:1'],
        'icon'          => ['required'],
        'ismenu'        => ['required', 'in:1,2'],
        'isrouter'      => ['required', 'in:1,2'],
        'name'          => ['required'],
        'pid'           => ['required', 'num'],
        'status'        => ['required', 'in:1,2'],
        'title'         => ['required'],
        'sort'          => ['required', 'num', 'min:0', 'max:1000'],
        'remark'        => ['str'],
        'methods'       => ['required', 'methods'],
        'callback'      => ['required', 'str'],
        'befor'         => ['str'],
        'after'         => ['str'],
        'rules'         => ['required', 'checkAuthRule'],
        'uids'          => ['required', 'checkAuthRule'],
        'username'      => ['required', 'str', 'maxLength:12', 'minLength:3'],
        'password'      => ['required', 'str', 'maxLength:16', 'minLength:6'],
        'avatar'        => ['required', 'str', 'avatar:jpg,jpeg,png'],
        'deadline'      => ['str']
    ];

    /**
     * 错误提示信息
     *
     * @var array
     */
    public $message = [
        'idx'           => '参数异常',
        'icon'          => '请选择对应icon',
        'ismenu'        => '请选择是否为菜单',
        'isrouter'      => '请选择是否为路由',
        'name'          => '请输入正确的规则',
        'pid'           => '请选择对应的父级',
        'status'        => '请选择正确的状态',
        'title'         => '请输入对应的标题',
        'sort'          => '请输入正确的权重值(0 <= x < 1000)',
        'remark'        => '请输入合法的备注',
        'methods'       => '请选择合法的请求方式',
        'callback'      => '请输入回调类方法',
        'befor'         => '请输入前置中间件',
        'after'         => '请输入后置中间件',
        'rules'         => '权限异常',
        'uids'          => '用户参数错误',
        'username'      => [
            'required'  => '用户名必须',
            'maxLength' => '用户名长度不能超过12',
            'minLength' => '用户名长度不能小于3',
        ],
        'password'      => [
            'required'  => '密码必须',
            'maxLength' => '密码长度不能超过16',
            'minLength' => '密码长度不能小于6',
        ],
        'avatar'        => '头像只允许使用jpg,jpeg,png格式'
    ];

    /**
     * 验证场景
     *
     * @var array
     */
    public $scope = [
        'add_rule'      => ['pid', 'status', 'title', 'remark'],
        'save_rule'     => ['pid', 'status', 'title', 'remark', 'idx'],
        'route'         => ['methods', 'callback', 'befor', 'after', 'idx'],
        'add_group'     => ['status', 'title', 'pid'],
        'modify_group'  => ['status', 'title', 'pid', 'idx', 'rules'],
        'bind_group'    => ['idx', 'uids'],
        'login'         => ['username', 'password'],
        'add_user'      => ['username', 'password'],
        'edit_user'     => ['idx', 'deadline'],
        'reset_password' => ['idx', 'password'],
        'reset_status'  => ['idx', 'status'],
        'password'      => ['password']
    ];

    /**
     * 验证请求类型
     *
     * @return boolean
     */
    protected function methods($value)
    {
        if (!is_array($value)) {
            return false;
        }
        foreach ($value as $item) {
            if (!in_array($item, ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'])) {
                return false;
            }
        }

        return true;
    }

    /**
     * 验证规则路由
     *
     * @param  string $value [description]
     * @return boolean
     */
    public function checkAuthRule($value)
    {
        $rules = explode(",", $value);
        foreach ($rules as $v) {
            if (!is_numeric($v) || ($v % 1 !== 0)) {
                return false;
            }
        }

        return true;
    }

    /**
     * 自定义验证头像后缀
     *
     * @param  string $val  [description]
     * @param  array $rule [description]
     * @return boolean
     */
    public function avatar($val, $rule)
    {
        // 获取文件后缀
        $img = explode(".", $val);
        $ext = $img[count($img) - 1];

        $rules = explode(",", $rule);

        return in_array($ext, $rules);
    }
}
